package com.r2r.fetus;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.LinkedList;

/**
 * util class
 *
 * @author zcg
*/
public class Util {
	public static int getInt1(byte[] b, int offset) {
		return b[offset] & 0x000000FF;
	}

	public static int getInt2(byte[] b, int offset) {
		return b[offset++] & 0x000000FF | b[offset] & 0x0000FF00;
	}

	/**
	 * get a int from a byte array start from the specifield offset
	 *
	 * @param    b
	 * @param    offset
	*/
	public static int getInt3(byte[] b, int offset) {
		return b[offset++] & 0x000000FF | b[offset++] & 0x0000FF00 | b[offset] & 0x00FF0000;
	}

	/**
	 * get a int from a byte array start from the specifiled offset
	 *
	 * @param    b
	 * @param    offset
	*/
	public static long getIntLong(byte[] b, int offset) {
		return b[offset++] & 0x000000FFL | b[offset++] << 8 & 0x0000FF00L | b[offset++] << 16 & 0x00FF0000L | b[offset] << 24 & 0xFF000000L;
	}

	/**
	 * string ip to long ip
	 *
	 * @param    ip
	 * @return    long
	*/
	public static long ip2long(String ip) {
		String[] p = ip.split("\\.");
		if (p.length != 4) {
			return 0;
		}

		int p1 = Integer.valueOf(p[0]) << 24 & 0xFF000000;
		int p2 = Integer.valueOf(p[1]) << 16 & 0x00FF0000;
		int p3 = Integer.valueOf(p[2]) << 8 & 0x0000FF00;
		int p4 = Integer.valueOf(p[3]) << 0 & 0x000000FF;

		return (p1 | p2 | p3 | p4) & 0xFFFFFFFFL;
	}

	/**
	 * check the validate of the specifeld ip address
	 *
	 * @param    ip
	 * @return    boolean
	*/
	public static boolean isIpAddress(String ip) {
		String[] p = ip.split("\\.");
		if (p.length != 4) {
			return false;
		}

		for (String pp : p) {
			if (pp.length() > 3) {
				return false;
			}
			int val = Integer.valueOf(pp);
			if (val > 255) {
				return false;
			}
		}

		return true;
	}

	/**
	 * int to ip string
	 *
	 * @param    ip
	 * @return    string
	*/
	public static String long2ip(long ip) {
		StringBuilder sb = new StringBuilder();

		sb.append(ip >> 24 & 0xFF).append('.').append(ip >> 16 & 0xFF).append('.').append(ip >> 8 & 0xFF).append('.').append(ip >> 0 & 0xFF);

		return sb.toString();
	}

	/**
	 * write specfield bytes to a byte array start from offset
	 *
	 * @param    b
	 * @param    offset
	 * @param    v
	 * @param    bytes
	*/
	public static void write(byte[] b, int offset, long v, int bytes) {
		for (int i = 0; i < bytes; i++) {
			b[offset++] = (byte) (v >>> 8 * i & 0xFF);
		}
	}

	/**
	 * write a int to a byte array
	 *
	 * @param    b
	 * @param    offet
	 * @param    v
	*/
	public static void writeIntLong(byte[] b, int offset, long v) {
		b[offset++] = (byte) (v >> 0 & 0xFF);
		b[offset++] = (byte) (v >> 8 & 0xFF);
		b[offset++] = (byte) (v >> 16 & 0xFF);
		b[offset] = (byte) (v >> 24 & 0xFF);
	}
	
	/* Convert byte[] to hex string.这里我们可以将byte转换成int，然后利用Integer.toHexString(int)来转换成16进制字符串。  
	 * @param src byte[] data  
	 * @return hex string  
	 */     
	public static String bytesToHexString(byte[] src){  
	    StringBuilder stringBuilder = new StringBuilder("");  
	    if (src == null || src.length <= 0) {  
	        return null;  
	    }  
	    for (int i = 0; i < src.length; i++) {  
	        int v = src[i] & 0xFF;  
	        String hv = Integer.toHexString(v);  
	        if (hv.length() < 2) {  
	            stringBuilder.append(0);  
	        }  
	        stringBuilder.append(hv);  
	    }  
	    return stringBuilder.toString();  
	}  
	/** 
	 * Convert hex string to byte[] 
	 * @param hexString the hex string 
	 * @return byte[] 
	 */  
	public static byte[] hexStringToBytes(String hexString) {  
	    if (hexString == null || hexString.equals("")) {  
	        return null;  
	    }  
	    hexString = hexString.toUpperCase();  
	    int length = hexString.length() / 2;  
	    char[] hexChars = hexString.toCharArray();  
	    byte[] d = new byte[length];  
	    for (int i = 0; i < length; i++) {  
	        int pos = i * 2;  
	        d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));  
	    }  
	    return d;  
	}  
	/** 
	 * Convert char to byte 
	 * @param c char 
	 * @return byte 
	 */  
	 private static byte charToByte(char c) {  
	    return (byte) "0123456789ABCDEF".indexOf(c);  
	}	
	 
	// char[]->byte[]
	public static byte[] getBytes (char[] chars, int length, String charset) { 
		 Charset cs = Charset.forName (charset); 
		 CharBuffer cb = CharBuffer.allocate (length);
		 cb.put (chars); 
		 for(int i=cb.position();i<length;i++)
			 cb.put(' ');
		 cb.flip (); 
		 ByteBuffer bb = cs.encode (cb); 
		 return bb.array();
	} 
	// byte[]->char[] 
	public static char[] getChars (byte[] bytes, int offset, int length, String charset) { 
		Charset cs = Charset.forName (charset); 
		ByteBuffer bb = ByteBuffer.allocate (length); 
		bb.put(bytes, offset, length); 
		bb.flip (); 
		CharBuffer cb = cs.decode (bb); 
		return cb.array();
	}
	/**
	 * 在buffer中查找byte数组的位置,找到返回位置，并定位到该位置。找不到，返回-1
	 * @param buffer
	 * @param bytes
	 * @return
	 */
	public static int indexOfBytes(ByteBuffer buffer, byte[] bytes){
		int idx=-1;
		int bytesLength = bytes.length;
		byte[] read = new byte[bytesLength];
		int limit = buffer.limit();
		int pos = buffer.position();
		int position = 0;
		for(int i=0;i<limit-bytesLength;i++) {
			buffer.get(read,0,bytesLength);
			position = buffer.position();
			// System.out.println(bytesToHexString(read));  
			if(Arrays.equals(read,bytes)) {
				buffer.position(position-bytesLength);
				return position-bytesLength;
			}
			buffer.position(position-bytesLength+1);
		}
		buffer.position(pos);
		return idx;
	}
	/**
	 * 在buffer中查找开始是begin1,begin2,间隔step个字节，结尾是end1,end2的字符串是否存在
	 */
	public static boolean getBytesPosition(ByteBuffer buffer, byte[] bytes, byte[]bytes1) {
		int bytesLength = bytes.length;
		byte[] read = new byte[bytesLength];
		int limit = buffer.limit();
		int position = 0;
		for(int i=0;i<limit-bytesLength;i++) {
			buffer.get(read, 0, bytesLength);
			position = buffer.position();
			// System.out.println(bytesToHexString(read));  
			
			if(Arrays.equals(read,bytes)||Arrays.equals(read, bytes1)) {
				return true;
			}
			buffer.position(position-bytesLength+1);
		}
		return false;
	}

	/**
	 * 在buffer中查找开始是begin1,begin2,间隔step个字节，结尾是end1,end2的字符串是否存在
	 */
	public static boolean getBytesPosition(ByteBuffer buffer, byte begin1, byte begin2 ,byte end1, byte end2, int step) {
		String s = Util.bytesToHexString(buffer.array());
		while(buffer.hasRemaining()){
			byte b= buffer.get();
			if(b==begin1) {
				b = buffer.get();
				if(b==begin2) {
					buffer.position(buffer.position()+step);
					b = buffer.get();
					if(b==end1) {
						b = buffer.get();
						if(b==end2) {
							return true;
						}
					}
				}
			}
//			if(buffer.get(0)==begin1&&buffer.get(1)==begin2) {
//				if(buffer.get(20)==end1&&buffer.get(21)==end2) {
//					buffer.position(22);
//					return true;
//				}
//			}
//			else
//				buffer.get();
		}
		buffer.clear();
		return false;
	}
	/**
	 * short to byte[]
	 * @param n
	 * @return
	 */
	public static byte[] shortToBytes(short n) {
		byte[] b = new byte[2];
		b[1] = (byte) (n & 0xff);
		b[0] = (byte) ((n >> 8) & 0xff);
		return b;
	}
	/**
	 * byte[] to short
	 * @param b
	 * @return
	 */
	public static short byteToShort(byte b) {	
		return (short) (b & 0xff);
	}
	/**
	 * byte[] to short
	 * @param b
	 * @return
	 */
	public static short bytesToShort(byte[] b) {	
		return (short) (b[1] & 0xff	| (b[0] & 0xff) << 8);
	}

	/**
	 * short to byte[]
	 * @param n
	 * @return
	 */
	public static byte[] shortsToUnsignedBytes(Short[] n) {
		byte[] b = new byte[n.length];
		for(int i=0;i<n.length;i++)
			b[i] = (byte) (n[i] & 0xff);
		return b;
	}
	/**
	 * short to short[]
	 * @param n
	 * @return
	 */
	public static short[] listToShorts(short[]b,LinkedList list) {
		for(int i=0;i<list.size();i++)
			b[i] = (short) list.get(i);
		return b;
	}
	/**
	 * short to short[]
	 * @param n
	 * @return
	 */
	public static byte[] listToBytes(byte[]b,LinkedList list) {
		for(int i=0;i<list.size();i++)
			b[i] = (byte) ((short)list.get(i) & 0xff);
		return b;
	}
	/**
	 * short to short[]
	 * @param n
	 * @return
	 */
	public static short[] shortsToShorts(Object[] n) {
		short[] b = new short[n.length];
		for(int i=0;i<n.length;i++)
			b[i] = (short) n[i];
		return b;
	}
	/**
	 * LinkedList<Short>  to byte[]
	 * short to byte[]
	 * @param n
	 * @return
	 */
	public static byte[] shortListToUnsignedBytes(Object[] n) {
		byte[] b = new byte[n.length];
		for(int i=0;i<n.length;i++)
			b[i] = (byte) (((short)n[i]) & 0xff);
		return b;
	}
	
	public static String arrayJoin2String(int[] ary) {
		StringBuffer sb = new StringBuffer();
		for(int i = 0; i < ary.length; i++){
			sb.append(ary[i]+",");
		} 
		String newStr = sb.toString();
		return newStr.substring(0, newStr.length() - 1);
	}
	// 写文本文件
	public static void writeTextFile(String fileName, String txt) {
		BufferedWriter out = null;
		try {
			out = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(fileName, true)));
			out.write(txt);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
		try {
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) throws Exception {
		
	}
}
